<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="generator" content="AsciiDoc 8.5.2" />
<title>Gerrit Code Review - Change-Ids</title>
<style type="text/css">
/* Debug borders */
p, li, dt, dd, div, pre, h1, h2, h3, h4, h5, h6 {
/*
  border: 1px solid red;
*/
}

body {
  margin: 1em 5% 1em 5%;
}

a {
  color: blue;
  text-decoration: underline;
}
a:visited {
  color: fuchsia;
}

em {
  font-style: italic;
  color: navy;
}

strong {
  font-weight: bold;
  color: #083194;
}

tt {
  color: navy;
}

h1, h2, h3, h4, h5, h6 {
  color: #527bbd;
  font-family: sans-serif;
  margin-top: 1.2em;
  margin-bottom: 0.5em;
  line-height: 1.3;
}

h1, h2, h3 {
  border-bottom: 2px solid silver;
}
h2 {
  padding-top: 0.5em;
}
h3 {
  float: left;
}
h3 + * {
  clear: left;
}

div.sectionbody {
  font-family: serif;
  margin-left: 0;
}

hr {
  border: 1px solid silver;
}

p {
  margin-top: 0.5em;
  margin-bottom: 0.5em;
}

ul, ol, li > p {
  margin-top: 0;
}

pre {
  padding: 0;
  margin: 0;
}

span#author {
  color: #527bbd;
  font-family: sans-serif;
  font-weight: bold;
  font-size: 1.1em;
}
span#email {
}
span#revnumber, span#revdate, span#revremark {
  font-family: sans-serif;
}

div#footer {
  font-family: sans-serif;
  font-size: small;
  border-top: 2px solid silver;
  padding-top: 0.5em;
  margin-top: 4.0em;
}
div#footer-text {
  float: left;
  padding-bottom: 0.5em;
}
div#footer-badges {
  float: right;
  padding-bottom: 0.5em;
}

div#preamble {
  margin-top: 1.5em;
  margin-bottom: 1.5em;
}
div.tableblock, div.imageblock, div.exampleblock, div.verseblock,
div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
div.admonitionblock {
  margin-top: 1.0em;
  margin-bottom: 1.5em;
}
div.admonitionblock {
  margin-top: 2.0em;
  margin-bottom: 2.0em;
  margin-right: 10%;
  color: #606060;
}

div.content { /* Block element content. */
  padding: 0;
}

/* Block element titles. */
div.title, caption.title {
  color: #527bbd;
  font-family: sans-serif;
  font-weight: bold;
  text-align: left;
  margin-top: 1.0em;
  margin-bottom: 0.5em;
}
div.title + * {
  margin-top: 0;
}

td div.title:first-child {
  margin-top: 0.0em;
}
div.content div.title:first-child {
  margin-top: 0.0em;
}
div.content + div.title {
  margin-top: 0.0em;
}

div.sidebarblock > div.content {
  background: #ffffee;
  border: 1px solid silver;
  padding: 0.5em;
}

div.listingblock > div.content {
  border: 1px solid silver;
  background: #f4f4f4;
  padding: 0.5em;
}

div.quoteblock, div.verseblock {
  padding-left: 1.0em;
  margin-left: 1.0em;
  margin-right: 10%;
  border-left: 5px solid #dddddd;
  color: #777777;
}

div.quoteblock > div.attribution {
  padding-top: 0.5em;
  text-align: right;
}

div.verseblock > div.content {
  white-space: pre;
}
div.verseblock > div.attribution {
  padding-top: 0.75em;
  text-align: left;
}
/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
div.verseblock + div.attribution {
  text-align: left;
}

div.admonitionblock .icon {
  vertical-align: top;
  font-size: 1.1em;
  font-weight: bold;
  text-decoration: underline;
  color: #527bbd;
  padding-right: 0.5em;
}
div.admonitionblock td.content {
  padding-left: 0.5em;
  border-left: 3px solid #dddddd;
}

div.exampleblock > div.content {
  border-left: 3px solid #dddddd;
  padding-left: 0.5em;
}

div.imageblock div.content { padding-left: 0; }
span.image img { border-style: none; }
a.image:visited { color: white; }

dl {
  margin-top: 0.8em;
  margin-bottom: 0.8em;
}
dt {
  margin-top: 0.5em;
  margin-bottom: 0;
  font-style: normal;
  color: navy;
}
dd > *:first-child {
  margin-top: 0.1em;
}

ul, ol {
    list-style-position: outside;
}
ol.arabic {
  list-style-type: decimal;
}
ol.loweralpha {
  list-style-type: lower-alpha;
}
ol.upperalpha {
  list-style-type: upper-alpha;
}
ol.lowerroman {
  list-style-type: lower-roman;
}
ol.upperroman {
  list-style-type: upper-roman;
}

div.compact ul, div.compact ol,
div.compact p, div.compact p,
div.compact div, div.compact div {
  margin-top: 0.1em;
  margin-bottom: 0.1em;
}

div.tableblock > table {
  border: 3px solid #527bbd;
}
thead, p.table.header {
  font-family: sans-serif;
  font-weight: bold;
}
tfoot {
  font-weight: bold;
}
td > div.verse {
  white-space: pre;
}
p.table {
  margin-top: 0;
}
/* Because the table frame attribute is overriden by CSS in most browsers. */
div.tableblock > table[frame="void"] {
  border-style: none;
}
div.tableblock > table[frame="hsides"] {
  border-left-style: none;
  border-right-style: none;
}
div.tableblock > table[frame="vsides"] {
  border-top-style: none;
  border-bottom-style: none;
}


div.hdlist {
  margin-top: 0.8em;
  margin-bottom: 0.8em;
}
div.hdlist tr {
  padding-bottom: 15px;
}
dt.hdlist1.strong, td.hdlist1.strong {
  font-weight: bold;
}
td.hdlist1 {
  vertical-align: top;
  font-style: normal;
  padding-right: 0.8em;
  color: navy;
}
td.hdlist2 {
  vertical-align: top;
}
div.hdlist.compact tr {
  margin: 0;
  padding-bottom: 0;
}

.comment {
  background: yellow;
}

.footnote, .footnoteref {
  font-size: 0.8em;
}

span.footnote, span.footnoteref {
  vertical-align: super;
}

#footnotes {
  margin: 20px 0 20px 0;
  padding: 7px 0 0 0;
}

#footnotes div.footnote {
  margin: 0 0 5px 0;
}

#footnotes hr {
  border: none;
  border-top: 1px solid silver;
  height: 1px;
  text-align: left;
  margin-left: 0;
  width: 20%;
  min-width: 100px;
}


@media print {
  div#footer-badges { display: none; }
}

div#toc {
  margin-bottom: 2.5em;
}

div#toctitle {
  color: #527bbd;
  font-family: sans-serif;
  font-size: 1.1em;
  font-weight: bold;
  margin-top: 1.0em;
  margin-bottom: 0.1em;
}

div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
  margin-top: 0;
  margin-bottom: 0;
}
div.toclevel2 {
  margin-left: 2em;
  font-size: 0.9em;
}
div.toclevel3 {
  margin-left: 4em;
  font-size: 0.9em;
}
div.toclevel4 {
  margin-left: 6em;
  font-size: 0.9em;
}
/* Workarounds for IE6's broken and incomplete CSS2. */

div.sidebar-content {
  background: #ffffee;
  border: 1px solid silver;
  padding: 0.5em;
}
div.sidebar-title, div.image-title {
  color: #527bbd;
  font-family: sans-serif;
  font-weight: bold;
  margin-top: 0.0em;
  margin-bottom: 0.5em;
}

div.listingblock div.content {
  border: 1px solid silver;
  background: #f4f4f4;
  padding: 0.5em;
}

div.quoteblock-attribution {
  padding-top: 0.5em;
  text-align: right;
}

div.verseblock-content {
  white-space: pre;
}
div.verseblock-attribution {
  padding-top: 0.75em;
  text-align: left;
}

div.exampleblock-content {
  border-left: 3px solid #dddddd;
  padding-left: 0.5em;
}

/* IE6 sets dynamically generated links as visited. */
div#toc a:visited { color: blue; }
</style>
<script type="text/javascript">
/*<![CDATA[*/
window.onload = function(){asciidoc.footnotes(); asciidoc.toc(2);}
var asciidoc = {  // Namespace.

/////////////////////////////////////////////////////////////////////
// Table Of Contents generator
/////////////////////////////////////////////////////////////////////

/* Author: Mihai Bazon, September 2002
 * http://students.infoiasi.ro/~mishoo
 *
 * Table Of Content generator
 * Version: 0.4
 *
 * Feel free to use this script under the terms of the GNU General Public
 * License, as long as you do not remove or alter this notice.
 */

 /* modified by Troy D. Hanson, September 2006. License: GPL */
 /* modified by Stuart Rackham, 2006, 2009. License: GPL */

// toclevels = 1..4.
toc: function (toclevels) {

  function getText(el) {
    var text = "";
    for (var i = el.firstChild; i != null; i = i.nextSibling) {
      if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
        text += i.data;
      else if (i.firstChild != null)
        text += getText(i);
    }
    return text;
  }

  function TocEntry(el, text, toclevel) {
    this.element = el;
    this.text = text;
    this.toclevel = toclevel;
  }

  function tocEntries(el, toclevels) {
    var result = new Array;
    var re = new RegExp('[hH]([2-'+(toclevels+1)+'])');
    // Function that scans the DOM tree for header elements (the DOM2
    // nodeIterator API would be a better technique but not supported by all
    // browsers).
    var iterate = function (el) {
      for (var i = el.firstChild; i != null; i = i.nextSibling) {
        if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
          var mo = re.exec(i.tagName);
          if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
            result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
          }
          iterate(i);
        }
      }
    }
    iterate(el);
    return result;
  }

  var toc = document.getElementById("toc");
  var entries = tocEntries(document.getElementById("content"), toclevels);
  for (var i = 0; i < entries.length; ++i) {
    var entry = entries[i];
    if (entry.element.id == "")
      entry.element.id = "_toc_" + i;
    var a = document.createElement("a");
    a.href = "#" + entry.element.id;
    a.appendChild(document.createTextNode(entry.text));
    var div = document.createElement("div");
    div.appendChild(a);
    div.className = "toclevel" + entry.toclevel;
    toc.appendChild(div);
  }
  if (entries.length == 0)
    toc.parentNode.removeChild(toc);
},


/////////////////////////////////////////////////////////////////////
// Footnotes generator
/////////////////////////////////////////////////////////////////////

/* Based on footnote generation code from:
 * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
 */

footnotes: function () {
  var cont = document.getElementById("content");
  var noteholder = document.getElementById("footnotes");
  var spans = cont.getElementsByTagName("span");
  var refs = {};
  var n = 0;
  for (i=0; i<spans.length; i++) {
    if (spans[i].className == "footnote") {
      n++;
      // Use [\s\S] in place of . so multi-line matches work.
      // Because JavaScript has no s (dotall) regex flag.
      note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
      noteholder.innerHTML +=
        "<div class='footnote' id='_footnote_" + n + "'>" +
        "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
        n + "</a>. " + note + "</div>";
      spans[i].innerHTML =
        "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
        "' title='View footnote' class='footnote'>" + n + "</a>]";
      var id =spans[i].getAttribute("id");
      if (id != null) refs["#"+id] = n;
    }
  }
  if (n == 0)
    noteholder.parentNode.removeChild(noteholder);
  else {
    // Process footnoterefs.
    for (i=0; i<spans.length; i++) {
      if (spans[i].className == "footnoteref") {
        var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
        href = href.match(/#.*/)[0];  // Because IE return full URL.
        n = refs[href];
        spans[i].innerHTML =
          "[<a href='#_footnote_" + n +
          "' title='View footnote' class='footnote'>" + n + "</a>]";
      }
    }
  }
}

}
/*]]>*/
</script>
</head>
<body>
<div id="header">
<h1>Gerrit Code Review - Change-Ids</h1>
<span id="revnumber">version 2.3</span>
<div id="toc">
  <div id="toctitle">Table of Contents</div>
  <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
</div>
</div>
<div id="content">
<h2 id="_description">Description</h2>
<div class="sectionbody">
<div class="paragraph"><p>Gerrit Code Review sometimes relies upon Change-Id lines in the
bottom of a commit message to uniquely identify a change across all
drafts of it.  By including a unique Change-Id in the commit message,
Gerrit can automatically associate a new version of a change back
to its original review, even across cherry-picks and rebases.</p></div>
<div class="paragraph"><p>To be picked up by Gerrit, a Change-Id line must be in the bottom
portion (last paragraph) of a commit message, and may be mixed
together with the Signed-off-by, Acked-by, or other such footers.
For example:</p></div>
<div class="listingblock">
<div class="content">
<pre><tt>  $ git log -1
  commit 29a6bb1a059aef021ac39d342499191278518d1d
  Author: A. U. Thor &lt;author@example.com&gt;
  Date: Thu Aug 20 12:46:50 2009 -0700

      Improve foo widget by attaching a bar.

      We want a bar, because it improves the foo by providing more
      wizbangery to the dowhatimeanery.

      Bug: #42
      Change-Id: Ic8aaa0728a43936cd4c6e1ed590e01ba8f0fbf5b
      Signed-off-by: A. U. Thor &lt;author@example.com&gt;
      CC: R. E. Viewer &lt;reviewer@example.com&gt;</tt></pre>
</div></div>
<div class="paragraph"><p>In the above example, <tt>Ic8aaa0728a43936cd4c6e1ed590e01ba8f0fbf5b</tt>
is the unique identity assigned to this change.  It does not match
the commit name, <tt>29a6...</tt>, as the change may have been amended or
rebased to address reviewer comments since its initial inception.</p></div>
<div class="paragraph"><p>To avoid confusion with commit names, Change-Ids typically are with
an uppercase <tt>I</tt>.</p></div>
</div>
<h2 id="_creation">Creation</h2>
<div class="sectionbody">
<div class="paragraph"><p>Gerrit Code Review provides a standard <em>commit-msg</em> hook which
can be installed in the local Git repository to automatically
create and insert a unique Change-Id line during <tt>git commit</tt>.
To install the hook, copy it from Gerrit&#8217;s daemon:</p></div>
<div class="literalblock">
<div class="content">
<pre><tt>$ scp -p -P 29418 john.doe@review.example.com:hooks/commit-msg .git/hooks/</tt></pre>
</div></div>
<div class="literalblock">
<div class="content">
<pre><tt>$ curl http://review.example.com/tools/hooks/commit-msg</tt></pre>
</div></div>
<div class="paragraph"><p>For more details, see <a href="cmd-hook-commit-msg.html">commit-msg</a>.</p></div>
</div>
<h2 id="_change_upload">Change Upload</h2>
<div class="sectionbody">
<div class="paragraph"><p>During upload by pushing to a <tt>refs/for/*</tt> or <tt>refs/heads/*</tt>
branch, Gerrit will use the Change-Id line to:</p></div>
<div class="ulist"><ul>
<li>
<p>
Create a new change
</p>
<div class="paragraph"><p>If this is the first time it has seen the Change-Id mentioned in
the commit message, Gerrit will create a new change for review.</p></div>
</li>
<li>
<p>
Update an existing change
</p>
<div class="paragraph"><p>If Gerrit has seen this Change-Id before, but has not yet seen this
new commit object, Gerrit will add the new commit as a new patch
set on the existing change.</p></div>
</li>
<li>
<p>
Close an existing change
</p>
<div class="paragraph"><p>If Gerrit has seen this Change-Id before, and the commit is being
pushed directly into a branch, the existing change is updated with
the new commit, and the change is closed and marked as merged.</p></div>
</li>
</ul></div>
<div class="paragraph"><p>If a Change-Id line is not present in the commit message, Gerrit will
automatically generate its own Change-Id and display it on the web.
This line can be manually copied and inserted into an updated commit
message if additional revisions to a change are required.</p></div>
<div class="paragraph"><p>For more details on using git push to upload changes to Gerrit,
see <a href="user-upload.html#push_create">creating changes by git push</a>.</p></div>
</div>
<h2 id="_git_tasks">Git Tasks</h2>
<div class="sectionbody">
<h3 id="new">Creating a new commit</h3><div style="clear:left"></div>
<div class="paragraph"><p>When creating a new commit, ensure the <em>commit-msg</em> hook has been
installed in your repository (see above), and don&#8217;t put a Change-Id
line in the commit message.  When you exit the editor, git will call
the hook, which will automatically generate and insert a unique
Change-Id line.  You can inspect the modified message after the
commit is complete by executing <tt>git show</tt>.</p></div>
<h3 id="amend">Amending a commit</h3><div style="clear:left"></div>
<div class="paragraph"><p>When amending a commit with <tt>git commit --amend</tt>, leave the
Change-Id line unmodified in the commit message.  This will allow
Gerrit to automatically update the change with the amended commit.</p></div>
<h3 id="rebase">Rebasing a commit</h3><div style="clear:left"></div>
<div class="paragraph"><p>When rebasing a commit, leave the Change-Id line unmodified in the
commit message.  This will allow Gerrit to automatically update
the change with the rebased commit.</p></div>
<h3 id="squash">Squashing commits</h3><div style="clear:left"></div>
<div class="paragraph"><p>When squashing several commits together, try to preserve only one
Change-Id line, and remove the others from the commit message.
When faced with multiple lines, try to preserve a line which was
already uploaded to Gerrit Code Review, and thus has a corresponding
change that reviewers have already examined and left comments on.
If you aren&#8217;t sure which lines Gerrit knows about, try copying and
pasting the lines into the search box in the top-right.</p></div>
<div class="paragraph"><p>If Gerrit already knows about more than one Change-Id, pick one
to keep in the squashed commit message, and manually abandon the
other changes through the web interface.</p></div>
<h3 id="cherry-pick">Cherry-picking a commit</h3><div style="clear:left"></div>
<div class="paragraph"><p>When cherry-picking a commit, leave the Change-Id line alone to
have Gerrit treat the cherry-picked commit as a replacement for
the existing change.  This can be very useful if the project has
a fast-forward-only merge policy, and the submitter is downloading
and cherry-picking individual changes prior to submission, such as
by <a href="cmd-cherry-pick.html">gerrit-cherry-pick</a>.</p></div>
<div class="paragraph"><p>Or, you may wish to delete the Change-Id line and force a new
Change-Id to be generated automatically, thus creating an entirely
new change record for review.  This may be useful when backporting
a change from the current development branch to a maintenance
release branch.</p></div>
<h3 id="update-old">Updating an old commit</h3><div style="clear:left"></div>
<div class="paragraph"><p>If a commit was created before the availability of Change-Id support,
or was created in a Git repository that was missing the <em>commit-msg</em>
hook, simply copy the "<tt>Change-Id: I...</tt>" line from the first line
of the Description section of the change and amend it to the bottom
of the commit message.  Any subsequent uploads of the commit will
be automatically associated with the prior change.</p></div>
</div>
<hr style="
  height: 2px;
  color: silver;
  margin-top: 1.2em;
  margin-bottom: 0.5em;
">
<div class="paragraph"><p>Part of <a href="index.html">Gerrit Code Review</a></p></div>
</div>
<div id="footnotes"><hr /></div>
<div id="footer">
<div id="footer-text">
Version 2.3<br />
Last updated 2012-02-06 15:08:50 MDT
</div>
</div>
</body>
</html>
